#ifndef MAX_GROUPS_X
#define MAX_GROUPS_X 8
#endif

cbuffer cbPerLightVolume
{
	float3 gLightVolPos;
	float3 gLightVolScale;
};

Texture1D gLightVolPosTex;
Texture1D gLightVolScaleTex;
Texture1D<uint> gLightVolSectionThreadOffsetXTex;

RWTexture3D<uint> gLightTex0;
RWTexture3D<uint> gLightTex1;
RWTexture3D<uint> gLightTex2;
#ifndef AXES_4
RWTexture3D<uint> gLightTex3;
RWTexture3D<uint> gLightTex4;
#endif

float4 rgba8_as_uint_to_float4(uint input)  
{  
	float4 output;  
	output.x = (float)  (input      & 0x000000ff)  / 255;  
	output.y = (float)(((input>> 8) & 0x000000ff)) / 255;  
	output.z = (float)(((input>>16) & 0x000000ff)) / 255;  
	output.w = (float)  (input>>24)                / 255;  
	return output;  
} 

uint float_to_uint(float value, float scale)  
{  
	return (uint)floor(value * scale + 0.5f); 
}  
 
uint float4_to_rgba8_as_uint(float4 input)  
{  
	uint output =  ( (float_to_uint(saturate(input.x), 255))     |  
					 (float_to_uint(saturate(input.y), 255)<< 8) |  
					 (float_to_uint(saturate(input.z), 255)<<16) |  
					 (float_to_uint(saturate(input.w), 255)<<24) );  
	return output;  
}

#ifdef AXES_4
void read4Axes(in int3 texCoord, out float3 axis0, out float3 axis1, out float3 axis2, out float3 axis3)
{
	float4 sample0 = rgba8_as_uint_to_float4(gLightTex0[texCoord]);
	float4 sample1 = rgba8_as_uint_to_float4(gLightTex1[texCoord]);
	float4 sample2 = rgba8_as_uint_to_float4(gLightTex2[texCoord]);

	axis0 = sample0.xyz;
	axis1 = sample1.xyz;
	axis2 = sample2.xyz;
	axis3 = float3(sample0.w, sample1.w, sample2.w);
}

void write4Axes(int3 texCoord, float3 axis0, float3 axis1, float3 axis2, float3 axis3)
{
	gLightTex0[texCoord] = float4_to_rgba8_as_uint(float4(axis0, axis3.x));
	gLightTex1[texCoord] = float4_to_rgba8_as_uint(float4(axis1, axis3.y));
	gLightTex2[texCoord] = float4_to_rgba8_as_uint(float4(axis2, axis3.z));
}
#else
void read6Axes(in int3 texCoord, out float3 xPos, out float3 xNeg, out float3 yPos, out float3 yNeg, out float3 zPos, out float3 zNeg)
{
	float4 sample0 = rgba8_as_uint_to_float4(gLightTex0[texCoord]);
	float4 sample1 = rgba8_as_uint_to_float4(gLightTex1[texCoord]);
	float4 sample2 = rgba8_as_uint_to_float4(gLightTex2[texCoord]);
	float4 sample3 = rgba8_as_uint_to_float4(gLightTex3[texCoord]);
	float4 sample4 = rgba8_as_uint_to_float4(gLightTex4[texCoord]);

	xPos = sample0.xyz;
	xNeg = sample1.xyz;
	yPos = sample2.xyz;
	yNeg = sample3.xyz;
	zPos = sample4.xyz;
	zNeg = float3(sample0.w, sample1.w, sample2.w);
}

void write6Axes(int3 texCoord, float3 xPos, float3 xNeg, float3 yPos, float3 yNeg, float3 zPos, float3 zNeg)
{
	gLightTex0[texCoord] = float4_to_rgba8_as_uint(float4(xPos, zNeg.x));
	gLightTex1[texCoord] = float4_to_rgba8_as_uint(float4(xNeg, zNeg.y));
	gLightTex2[texCoord] = float4_to_rgba8_as_uint(float4(yPos, zNeg.z));
	gLightTex3[texCoord] = float4_to_rgba8_as_uint(float4(yNeg, 0));
	gLightTex4[texCoord] = float4_to_rgba8_as_uint(float4(zPos, 0));
}
#endif
